package com.flute.haflute.common;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import com.flute.haflute.jobbox.common.tools.OSUtil;
import com.flute.haflute.monitor.Cpu;

/**
 * 读取分布式集群的配置，平台启动时调用，从硬盘读取数据，初始化系统环境 ClusterContext。
 * 
 */
public class ClusterConfLoader {
	private static boolean loaded = false;

	private static String cloudConfFile = "conf/cluster-conf.xml";

	public static void loadGlobalContext() throws JDOMException, IOException {
		if (!loaded) {
			loadConfiguration();
			loaded = true;
		}
	}

	/**
	 * 具体的配置读取函数
	 */
	private static void loadConfiguration() throws JDOMException, IOException {
		SAXBuilder builder = new SAXBuilder();
		Document doc = builder.build(new File(ClusterContext.getRootDir()
				+ cloudConfFile));
		Element root = doc.getRootElement();
		Element masters = root.getChild("masters");
		loadClusterMastersInfo(masters);

		Element heartbeat = root.getChild("heartbeat");
		loadHeartBeatParams(heartbeat);

		Element network = root.getChild("network");
		loadNetWorkParams(network);

		Element physicalenvironment = root.getChild("physical_environment");
		loadPhysicalParams(physicalenvironment);

		Element monitor = root.getChild("monitor");
		loadMonitorInfo(monitor);

	}

	private static void loadMonitorInfo(Element monitor) {
		String monitorMsgAge = monitor.getChildText("monitorMsgAge");
		ClusterContext.setMonitorMsgAge(Integer.parseInt(monitorMsgAge));

		String fileSize = monitor.getChildText("fileSize");
		ClusterContext.setFileSize(Integer.parseInt(fileSize));

		Element monitorMsgSort = monitor.getChild("monitorMsgSort");
		List<Element> list = monitorMsgSort.getChildren("topic");
		Map<String, String> map = new HashMap<String, String>();
		for (Element topic : list) {
			map.put(topic.getText(), topic.getAttributeValue("sortval"));
		}
		ClusterContext.setTopics(map);
	}

	private static void loadPhysicalParams(Element physicalenvironment) {
		int cpuCores = -1;
		if (physicalenvironment != null) {
			try {
				cpuCores = Integer.parseInt(physicalenvironment
						.getChildText("cpucores"));
			} catch (Exception e) {
				e.printStackTrace();
			}
			cpuCores = new Cpu().getTotalCpuCores(cpuCores);
			ClusterContext.setCpucores(cpuCores);
			String configuredLocalIp = physicalenvironment
					.getChildText("ipaddress");
			if (configuredLocalIp != null) {
				ClusterContext.setLocalAddress(OSUtil.getLocalHostAddress(true,
						configuredLocalIp));
			} else {
				ClusterContext.setLocalAddress(OSUtil.getLocalHostAddress(
						false, null));
			}
		}
	}

	private static void loadNetWorkParams(Element networkEle) {
		String rmiPort = networkEle.getChildText("rmiPort");
		ClusterContext.setRMIPort(Integer.parseInt(rmiPort));
	}

	/** 读取分布式平台的参数配置 */
	private static void loadHeartBeatParams(Element heartBeatEle)
			throws IOException {
		String port = heartBeatEle.getChildText("listenPort");
		ClusterContext.setHeartBeatPort(Integer.parseInt(port));

		String interval = heartBeatEle.getChildText("interval");
		ClusterContext.setHeartBeatInterval(Integer.parseInt(interval) * 1000);

		String maxFailures = heartBeatEle.getChildText("maxFailuresAllow");
		ClusterContext.setHeartBeatFailures(Integer.parseInt(maxFailures));

		String maxTries = heartBeatEle.getChildText("maxTryTimesAllow");
		ClusterContext.setHeartBeatTries(Integer.parseInt(maxTries));
	}

	/**
	 * 从配置文件中读取Hadoop的配置
	 */
	private static void loadClusterMastersInfo(Element masterElem) {
		if (masterElem == null)
			return;
		Element dMEle = masterElem.getChild("DM");
		String dM = dMEle.getTextTrim();
		ClusterContext.setDM(dM);

		Element bDMEle = masterElem.getChild("BDM");
		String bDM = bDMEle.getTextTrim();
		ClusterContext.setBDM(bDM);
	}

	public static void main(String[] args) {
		try {
			ClusterConfLoader.loadGlobalContext();
			System.out.println(ClusterContext.getDM());
		} catch (IOException e) {
			e.printStackTrace();
		} catch (JDOMException e) {
			e.printStackTrace();
		}
	}
}
